<?php
/*
# ------------------------------------------------------------------------
# JA Halite - Version 1.0 - Licence Owner JA180572
# ------------------------------------------------------------------------
# Copyright (C) 2004-2009 J.O.O.M Solutions Co., Ltd. All Rights Reserved.
# @license - Copyrighted Commercial Software
# Author: J.O.O.M Solutions Co., Ltd
# Websites:  http://www.joomlart.com -  http://www.joomlancers.com
# This file may not be redistributed in whole or significant part.
# ------------------------------------------------------------------------
*/ 
 
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.plugin.plugin' );
jimport('joomla.application.module.helper');
// require interface ja usersettting.
require_once( dirname(__FILE__).DS.'plg_jausersetting'.DS.'ija_usersetting.php' );
require_once( dirname(__FILE__).DS.'plg_jausersetting'.DS.'helper.php' );
			
class plgSystemPlg_jausersetting extends JPlugin {	
	
	/**
	 * @var string $prefix
	 *
	 * @access public.
	 */
	var $prefix = 'jaus_';
	/**
	 * @var array $modulesParams
	 *
	 * @access public.
	 */
	var $modulesParams = array();
	/**
	 * constructor.
	 */
	function plgSystemPlg_jausersetting(& $subject, $config){
		if (!defined("JA_USERSETTING_PLUGIN")) define("JA_USERSETTING_PLUGIN", 1);
		parent::__construct($subject, $config); 
	}
	
	/**
	 * process on After Initialise
	 */
	function onAfterRoute(){ 
		$this->plugin	=& JPluginHelper::getPlugin('system', 'plg_jausersetting');
		$this->plgParams	= new JParameter( $this->plugin->params );
		// if using ajax request
		if (JRequest::getVar('do') == 'ajax_usersetting') {
			$action = JRequest::getVar('action');
			$module = $this->getModuleInfo( JRequest::getInt('modid') );
			if( ($action != '') && ($module) ) {
				
				switch( $action ){
					case 'loadmodule': 	// process common action 
						if ( $module ) {
							echo JModuleHelper::renderModule( $module ); 
						}	
						break;
					case 'save_setting': // process common action 
						JAUserSettingHelper::saveSetting( $module->module );
						break;	
					case 'loadmodule_ajax':
						if ( $module ) {
							if( !isset($module->user) ) {
							   $module->user = '';
							}
							// pass user setting data into module
							$body = JModuleHelper::renderModule( $module ); 
							$body = $this->lookingForAndBindingHTML( $body );
							echo $body; exit;	
						}	
						break;	
					case 'save_reload_module':
						JAUserSettingHelper::saveSetting( $module->module );
						if ( $module ) {
							if( !isset($module->user) ) {
							   $module->user = '';
							}
							// pass user setting data into module
							$body = JModuleHelper::renderModule( $module ); 
							$body = $this->lookingForAndBindingHTML( $body );
							echo $body; exit;	
						}	
						break;	
					default: 			 // process private action
						if( $action == 'loadform'  && strtolower(JRequest::getVar('mode')) == 'xml' ) {
							echo $this->renderFromXMLFile( $module );
							exit();
						} 
						elseif( $processor = $this->getProcessorByModuleName($module->module) ) { 
							$processor->process( $action, $module, $this );
						}
						
				} // end switch
			} // endif;
			exit;
		}
		// non ajax.
		if (JRequest::getVar('do') == 'reset_usersetting') {
			JAUserSettingHelper::resetSetting();
			global $mainframe;
			$mainframe->redirect (JURI::base());
		}
		if(!defined("JA_USERSETTING_PLUGIN_HEADTAG") ) {
			$this->beforeBindingHTML();	
		}
	}
	
	
	
	/**
	 * get user model, it process storing data in the users table.
	 * 
	 * @return UserModelUser;
	 */
	function getUserModel(){
		if( class_exists('UserModelUser') ){
			return new UserModelUser();
		} else { 
			require_once( JPATH_ROOT. DS .'components' . DS. 'com_user' . DS . 'models'. DS . 'user.php' );
			return new UserModelUser();
		}	
	}
	
	/**
	 * get module's data by id.
	 *
	 * @param integer $moduleId
	 * @return stdClass which store module's data.
	 */
	function getModuleInfo( $moduleId ){
		if( isset($this->modulesParams[$moduleId]) ){
			return $this->modulesParams[$moduleId];
		}
		//get module as an object
		$db =& JFactory::getDBO();
		$db->setQuery("SELECT * FROM #__modules WHERE id='$moduleId' ");
		$modules = $db->loadObjectList();
		
		if( isset( $modules[0] ) ){
			$this->modulesParams[$moduleId] = $modules[0];
			return $modules[0];
		}
		return null;
	}
	
	/**
	 * processing on After Render.
	 */
	function onAfterRender(){
		$body = JResponse::getBody();
		
		$body = $this->lookingForAndBindingHTML( $body );
		JResponse::setBody($body);
	}
	
	/**
	 * Looking for configuration string and binding html for each configuration.
	 *
	 * @param string $body.
	 * @return string.
	 */
	function lookingForAndBindingHTML( $body ){
		// matching configuartion string.
		$matches = $this->parserConfigString( $body );

		if( $matches != null ) {
			// get params plugin object.
			
			foreach( $matches[1] as $key => $match ) {
				//replace multi space by a space.
				$tmp = trim(preg_replace('/\s+/', ' ', $match[0] ));
				if( $tmp == '' ) { 
					continue;
				}	
				$params = $this->parseParams($tmp);
				if( !empty($params) &&  isset($params['modid']) ){ 
					// 
					$module = $this->getModuleInfo( $params['modid'] );		
					if( !$module ) { 
						$body = $this->removeConfigString( $matches[0][$key][0], $body );
						continue;
					}
					
					if(isset($params['mode']) && strtolower(trim($params['mode'])) == 'xml' ){
						// get button or link
						$body = $this->onPrepareBindingHTML( $matches[0][$key][0], $body, $params, $this );		
					} else {
						// calling processor object.
						if( ($processor = $this->getProcessorByModuleName($module->module)) ) { 
							$body = $processor->onPrepareBindingHTML( $matches[0][$key][0], $body, $params, $this );
						}
					}
				}			
			}
		}
		return $body;
	}

	/**
	 * get processor by module's name.
	 *
	 * @param string $moduleName
	 * @return a centain Object equal null if could not found.
	 */
	function getProcessorByModuleName( $moduleName){
		
		$fileName = 'jaus_'.$moduleName.'.php';
		
		$processorModuleFile = JPATH_ROOT.DS.'modules'.DS.$moduleName.DS.'helper'.DS.'ja.usersetting.php';	
		if(file_exists($processorModuleFile) ) { 
			require_once ( $processorModuleFile ); 
		}
		$className = 'JAUserSetting'.ucfirst($moduleName);
		if( !class_exists($className) ) {
			$className = 'IJAUserSetting';
		}
		$object = new  $className();
		return ( $object ) ? $object : null;
	}
	
	/**
	 * render User setting form from a centain xml file.
	 *
	 * @param stdClass $module is object Data Module.
	 * @return string.
	 */
	function renderFromXMLFile( $module ){

		$configFile =JPATH_ROOT.DS.'modules'.DS.$module->module.DS.'jaus_'.$module->module.DS.'params.xml';
		if( !file_exists($configFile) ) { return ''; }
	
		$data = JAUserSettingHelper::getSetting( $module->module );
		$txt = '';
		if( isset($data['modid:'.$module->id]['params']) ){
		    foreach ( $data['modid:'.$module->id]['params'] as $k => $v ) {
				$txt .= "$k=$v\n";
			}  
		} // 	echo '<pre>'.print_r($txt,1); die;
		$params = new JParameter(  $txt, $configFile );
		$html = '<form action="" name="" class="">'
				. '<input type="hidden" name="group" value="modid:'.$module->id.'" />'
				. $params->render('params') 
				. '<input type="button" class="ja-submit" name="ja-submit" value="'.JText::_('SAVE').'" />'
				. '<input type="button" class="ja-cancel" value="'.JText::_('CANCEL').'" />'
				. '</form>';
		
		return $html;
	}

	/**
	 * process on prepare binding html: get setting button, it's entry point
	 *
	 * @param strign $configString 
	 * @param Strean $body that is HTML page.
	 * @param array $params parameters from configuration string.
	 * @param plgSystemJa_usersetting using for refer current plugin object.
	 */
	function onPrepareBindingHTML( $configString, $body, $params, $plugin ){
		$string = '';
		if( isset($params['modid']) ){
			$divID = 'ja-usersetting-item-'.$params['modid'];
			$link = 'index.php?do=ajax_usersetting&modid='.$params['modid'].'&mode=xml';
			$divIDReload = isset($params['idReload']) ? $params['idReload'] : '';
			$string =  '<div style="overflow:hidden" id="' . $divID . '" class="'. (isset($params['class']) ? $params['class'] : 'ja-usersetting') .'">';
			$string .= '<a onclick="return jaUserSetting.showForm( this, $(\''. $divID . '\'), \''.$divIDReload.'\')" href="'.$link.'" class="ja-usersetting-loadform">
							<span>'. $this->plgParams->get('lable_setting') .'</span>
						</a>';
			$string .= '</div>';	
			
		}
		return str_replace($configString, $string,  $body);
	}
	
	/**
	 * before binding HTML: load javascript tag, link tag.
	 */
	function beforeBindingHTML(  ){
		global $mainframe;
		$siteURL =  JURI::base(); 

		if( strpos($siteURL,'administrator') > 0 ) return ; 

		$baseURL    = $siteURL.'plugins/system/plg_jausersetting/';
		$headtag = array();
		$headtag[]  = JHTML::_('behavior.mootools');	
		$headtag[]  = "<script type='text/javascript' src='".$baseURL."script.js' charset=\"utf-8\"></script>";	

		if( $this->plgParams->get('load_css_file') ){	
			$this->stylesheet( $this );
		}
		
		$headtag[]  = "<script type='text/javascript'>"
					. "var jaUserSetting; window.addEvent( 'domready', function() {
							jaUserSetting = new JAUserSetting();
						});"
					. " </script>";
					
		$mainframe->addCustomHeadTag( implode("\n", $headtag) );

		define( "JA_USERSETTING_PLUGIN_HEADTAG", TRUE );
	}
	
	/**
	 * load css file allow override style by owner
	 *
	 * @param Instance of JPlugin $plugin
	 */
	function stylesheet( $plugin ) {
		global $mainframe; 
		JHTML::stylesheet('style.css','plugins/'.$plugin->_type.'/'.$plugin->_name.'/');
		if (is_file(JPATH_SITE.DS.'templates'.DS.$mainframe->getTemplate().DS.'css'.DS.$plugin->_name.".css"))
		JHTML::stylesheet($plugin->_name.".css",'templates/'.$mainframe->getTemplate().'/css/');
	} 
	 
	/**
	 * parser string in the body, check having configuration of ja-usersetting existed?
	 *
	 * @param string $text.
	 * @return array if having, equal null if not.
	 */
	function parserConfigString( $text ){
		if( preg_match_all('#{jausersetting(.*?)}#s', $text, $matches, PREG_OFFSET_CAPTURE) ){
			return $matches;
		}	
		return null;
	}
	
	/**
	 * get parameters from configuration string.
	 *
	 * @param string $string;
	 * @return array.
	 */
	function parseParams( $string ) {
		$string = html_entity_decode($string, ENT_QUOTES);
		$regex = "/\s*([^=\s]+)\s*=\s*('([^']*)'|\"([^\"]*)\"|([^\s]*))/";
		 $params = null;
		 if(preg_match_all($regex, $string, $matches) ){
				for ($i=0;$i<count($matches[1]);$i++){ 
				  $key 	 = $matches[1][$i];
				  $value = $matches[3][$i]?$matches[3][$i]:($matches[4][$i]?$matches[4][$i]:$matches[5][$i]);
				  $params[$key] = $value;
				}
		  }
		  return $params;
	}
	
	/**
	 * remove configuration string 
	 *
	 * @param string $configString
	 * @param string $body it's html.
	 * @return string .
	 */
	function removeConfigString( $configString, $body ){
		return str_replace($configString, '',  $body);
	}
}
?>